#include <iostream>
#include <pthread.h>
#include <queue>
#include <mutex> 
#include "lockGuard.hpp"  // 似乎有自带的locKguard类


using namespace std; 



const int gDefaultCap = 5 ;


template <class T>
class blockQueue
{
private:
    
    queue<T> _bq ;
    int _capaciy  ; // 队列容量
    pthread_mutex_t _mtx ;   // 锁
    pthread_cond_t _Empty;   // 判队列是否满
    pthread_cond_t _Full ;   // 判队列是否空  

private:

    bool isQueueEmpty()
    {
        return _bq.size() == 0 ;
    }

    bool isQueueFull()
    {
        return _bq.size() == _capaciy ;
    }

public: 

    blockQueue(int capacity = gDefaultCap)
        :_capaciy(capacity)
    {
        pthread_mutex_init(&_mtx , nullptr);
        pthread_cond_init(&_Empty,nullptr);
        pthread_cond_init(&_Full , nullptr);
    } 




    // 取任务和发布任务才是临界资源。
    void push(const T& in )
    {
        lockGuard lg(&_mtx);
        
        while(isQueueFull()) pthread_cond_wait(&_Full,&_mtx);  //给出的解释是：要100%保证临界资源是就绪的

       _bq.push(in);

        pthread_cond_signal(&_Empty);

    } //出代码块，lockGuard lg(&_mtx);设置的锁自动解锁。

    void pop(T* out)
    {
        lockGuard lg(&_mtx);

        while(isQueueEmpty()) pthread_cond_wait(&_Empty,&_mtx);

        *out = _bq.front();

        _bq.pop();

        pthread_cond_signal(&_Full);
    }

    ~blockQueue()
    {
        pthread_mutex_destroy(&_mtx);
        pthread_cond_destroy(&_Empty);
        pthread_cond_destroy(&_Full);
    }

};

